﻿<!DOCTYPE html>
<html>
<head>
<style>
.nodetext {
    font-size: 12px ;
    font-family: SimSun;
    fill:#000000;
}


.tooltip{  
    height: auto;  
    font-family: simsun;  
    font-size: 14px;  
    text-align: center;  
}
select#lineFontType.form-control , select#nodesFontType.form-control{
	width:184px;
}
.layout-split-east {
    border-left: 5px solid #E6EEF8;
}
</style>
<base href="<%=basePath%>">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
	<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>

<body>
<!-- 力导向图div -->
<div id="divid"></div>
<script>

$(document).ready(function(){
	showChart();
})

function showChart(){
	var data = {
	"links":[
	{ "source": "陆洋","target":"建银国际产业基金管理有限公司","relation" : "副董事长大人" ,"sourceId":"","targetId":"","sourceImg":"http://mail.tom.com/error/i2.gif","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"45","lineColor":"#458B00"},
	{ "source": "汪红辉"  , "target" : "乾行文化投资公司"  , "relation" : "总经理" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"#00FF00","sourceRadius":"30","targetRadius":"40","lineColor":"#EEEE00"},
	{ "source": "汪红辉"  , "target" : "乾行文化投资公司"  , "relation" : "总经理" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"#00FF00","sourceRadius":"30","targetRadius":"40","lineColor":"#EEEE00"},
	{ "source": "汪红辉"  , "target" : "天津裕丰股权投资管理有限公司" , "relation" : "董事" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"42","lineColor":"#0000CD"},
	{ "source": "汪红辉"  , "target" : "乾行文化投资公司"  , "relation" : "法人" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"40","lineColor":"#9AC0CD"},
	{ "source": "汪红辉" , "target" : "乾行文化投资公司" , "relation" : "董事长" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"40","lineColor":"#CD4F39"},
	{ "source": "汪红辉" , "target" : "建银国际产业基金管理有限公司"  , "relation" : "董事" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"45","lineColor":"#0000CD"},
	{ "source": "胡章宏" , "target" : "建银国际产业基金管理有限公司"   , "relation" : "董事长" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"30","targetRadius":"45","lineColor":"#CD4F39"},
	{ "source": "建银国际产业基金管理有限公司" , "target" : "胡章宏" , "relation" : "法人" ,"sourceId":"","targetId":"","sourceImg":"","targetImg":"","sourceColor":"","targetColor":"","sourceRadius":"45","targetRadius":"30","lineColor":"#9AC0CD"}
	]
	};
	var options = {};
	options.backgroundColor = "#D1EEEE";
	options.nodesFontType = "SimSun";
	options.nodesFontSize = 20;
	options.lineFontType = "SimHei";
	options.lineFontSize = 12;
	options.lineColor = "#000000";
	options.showExamples = true;
	options.examplesX = 20;
	options.examplesY = 450;
	options.examplesFontColor = "#000000";
	drawChart("divid",options,data);
}


function drawChart(divid,options,datas,dataFilter){
	var backgroundColor = options.backgroundColor; //背景颜色
	var nodesFontType = options.nodesFontType; //节点字体
	var nodesFontSize = options.nodesFontSize; //节点字号
	var lineFontType = options.lineFontType; //关系字体
	var lineFontSize = options.lineFontSize; //关系字号
	var lineColor = options.lineColor; //连线颜色
    var examplesFontColor = options.examplesFontColor; //关系示例字体颜色
	
	var width = 800; //画布宽
	var height = 500; //画布高
	var svgChart = d3.select("svg");
	svgChart.remove();
	
	var tip = $(".tooltip");
	if(tip.length > 0){
		tip.remove();
	}
	
	
	var sourceDatas = {};
	sourceDatas.links = [];
    for(var i = 0; i < datas.links.length; i++){
        var jsonObj = {};
        jsonObj.source = datas.links[i].source;
        jsonObj.target = datas.links[i].target;
        jsonObj.relation = datas.links[i].relation;
        jsonObj.sourceId = datas.links[i].sourceId;
        jsonObj.targetId = datas.links[i].targetId;
        jsonObj.sourceImg = datas.links[i].sourceImg;
        jsonObj.targetImg = datas.links[i].targetImg;
        jsonObj.sourceColor = datas.links[i].sourceColor;
        jsonObj.targetColor = datas.links[i].targetColor;
        jsonObj.sourceRadius = datas.links[i].sourceRadius;
        jsonObj.targetRadius = datas.links[i].targetRadius;
        jsonObj.lineColor = datas.links[i].lineColor;
        sourceDatas.links.push(jsonObj);
    }
    var resourceLinks = sourceDatas.links;
	
	
	if(dataFilter != undefined && dataFilter.length > 0){
		var indexArray = [];
		for(var i = 0; i < dataFilter.length; i++){
            for(var j = 0; j < resourceLinks.length; j++){
                if(resourceLinks[j].relation == dataFilter[i].relation && dataFilter[i].isShow == "false"){
                	indexArray.push(j);
                }
            }
        }
		if(indexArray.length > 0){
			var tempArray = [];
			for(var j = 0; j < resourceLinks.length; j++){
				for(var i = 0; i < indexArray.length; i++){
					if(indexArray[i] != j){
						if(i == indexArray.length-1){
							tempArray.push(resourceLinks[j]);
							break;
	                    }
						continue;
	                }else{
	                	break;
	                }
					
		        }
            }
			resourceLinks = tempArray;
		}
	}
	var links = resourceLinks;
	
	//关系分组  
    var linkGroup = {};  
    //对连接线进行统计和分组，不区分连接线的方向，只要属于同两个实体，即认为是同一组  
    var linkmap = {};  
    for(var i=0; i<links.length; i++){  
        var key = links[i].source<links[i].target?links[i].source+':'+links[i].target:links[i].target+':'+links[i].source;  
        if(!linkmap.hasOwnProperty(key)){  
            linkmap[key] = 0;  
        }  
        linkmap[key]+=1;  
        if(!linkGroup.hasOwnProperty(key)){  
            linkGroup[key]=[];  
        }  
        linkGroup[key].push(links[i]);  
    }  
    //为每一条连接线分配size属性，同时对每一组连接线进行编号  
    for(var i=0; i<links.length; i++){  
        var key = links[i].source<links[i].target?links[i].source+':'+links[i].target:links[i].target+':'+links[i].source;  
        links[i].size = linkmap[key];  
        //同一组的关系进行编号  
        var group = linkGroup[key];  
        //给节点分配编号  
        setLinkNumber(group);  
    }  
  
    //节点
    var nodes = {};  
    //关系对应颜色
    var relationColor = {};
  
    for(var i = 0; i < links.length; i++){
    	links[i].source = nodes[links[i].source] || (nodes[links[i].source] = {name: links[i].source,color:links[i].sourceColor,image:links[i].sourceImg,radius:links[i].sourceRadius});  
        links[i].target = nodes[links[i].target] || (nodes[links[i].target] = {name: links[i].target,color:links[i].targetColor,image:links[i].targetImg,radius:links[i].targetRadius});
    }
    
    var sourceData = datas.links;
    for(var i = 0; i < sourceData.length; i++){
        relationColor[sourceData[i].relation]={"relation":sourceData[i].relation,"lineColor":sourceData[i].lineColor};        
    }
    
        
    nodes = d3.values(nodes);
    relationColor = d3.values(relationColor);
    
    var examples_x = parseFloat(options.examplesX); //关系示例坐标x
    var examples_y = parseFloat(options.examplesY); //关系示例坐标y
    var examplesLength = 80;
    var examplesSize = Math.floor((width - examples_x)/examplesLength);
    var examplesRow = relationColor.length%examplesSize==0?relationColor.length/examplesSize:Math.ceil(relationColor.length/examplesSize);
    //计算关系示列位置
    for(var i = 1; i <= relationColor.length; i++){
    	var num = i%examplesSize==0?examplesSize:i%examplesSize;
    	relationColor[i-1].x = examples_x+(num-1)*examplesLength;
    	relationColor[i-1].y = examples_y+20*Math.ceil(i/examplesSize);
    }
    if(dataFilter == undefined){
    	dataFilter = [];
    	for(var i = 0; i < relationColor.length; i++){
    		dataFilter.push({"relation":relationColor[i].relation,"isShow":"true"});
    	}
    }
    
    
    //绑定相连节点
   for(var i = 0; i < nodes.length; i++){
    	for(var j = 0; j < links.length; j++){
    		if(nodes[i].name == links[j].source.name){
    			nodes[i][links[j].target.name] = {name: links[j].target.name};
    		}
    	    if(nodes[i].name == links[j].target.name){
    	    	nodes[i][links[j].source.name] = {name: links[j].source.name};
            }
    	}
    }
	
	var svg = d3.select("#"+divid).append("svg")
	                           .attr("width",width)
	                           .attr("height",height)
                               .attr("style","background-color:" + backgroundColor);
	if(options.showExamples=="true"){
		var examples = svg.selectAll(".examples")
        .data(relationColor)
        .enter()
        .append("svg:g")
        .attr("fill-opacity",function(d){
        	for(var i = 0; i < dataFilter.length; i++){
        		if(d.relation == dataFilter[i].relation && dataFilter[i].isShow == "false"){
        			return 0.2;
        		}
        	}
        	return 1;
        })
        .on("click", function(d){
        	for(var i = 0; i < dataFilter.length; i++){
        		if(dataFilter[i].relation == d.relation){
        			if(dataFilter[i].isShow == "true"){
        				dataFilter[i].isShow = "false";
        			}else{
        				dataFilter[i].isShow = "true";
        			}
        		}
        	}
        	drawChart(divid,options,datas,dataFilter);
         });
        
        
		examples.append("svg:path")          
		.attr("d", function(d){
		       var x1 = d.x;
		       var y1 = d.y;
		       var x2 = x1 + 20;
		       var y2 = y1;
		       return 'M'+x1+' '+y1+' L '+ x2 +' '+y2;
		   })
		.style("stroke",function(d){
		       if(d.lineColor == ""){
		           return lineColor;
		       }else{
		           return d.lineColor;
		       }
		   })
		.style("stroke-width",2.5);
		examples.append("svg:text")
		.style("font-size","14px")
		.style("fill",examplesFontColor)
		.attr("x",function(d){
		  if(d.relation.length > 3){
		      return d.x + 20 + 14*4/2;
		  }
		  return d.x + 20 + 14*d.relation.length/2;
		})
		.attr("y", function(d){
		  return d.y+5;
		})
		.attr('text-anchor', "middle")
		.text(function(d){
		  if(d.relation.length > 3){
		      return d.relation.substring(0,3)+"...";
		  }
		  return d.relation;
		})
		.on("mouseover",function(d){
		  tooltip.html("<span>"+d.relation+"</span>")
		  .style("left",(d3.event.pageX)+"px")
		  .style("top",(d3.event.pageY+20)+"px")
		  .style("display","block")
		  .style("position","absolute")
		  .style("opacity",1.0);
		})
		.on("mouseout",function(d,i){
		  tooltip.style("opacity",0.0);
		});
	}
	
	
	
	    //D3力导向布局
	    var force = d3.layout.force()
	                    .nodes(nodes)
	                    .links(links)
	                    .size([width,height])
	                    .linkDistance(200)
	                    .charge(-1500)
	                    .start();
	
		
	    //边             
	    var edges_path = svg.selectAll(".edgepath")
	                        .data(links)
	                        .enter()
	                        .append("path")
	                        .attr("marker-end",function(d,i){
	                        	var arrowMarker = svg.append("marker")
	                            .attr("id","arrow"+i)
	                            .attr("markerUnits","userSpaceOnUse")
	                            .attr("markerWidth","16")
	                            .attr("markerHeight","15")
	                            .attr("viewBox","0 0 12 12") 
	                            .attr("refX",9)
	                            .attr("refY",6)
	                            .attr("orient","auto")
	                            .append("svg:path")
	                            .attr("d","M2,2 L10,6 L2,10 L6,6 L2,2")
	                            .attr("fill",function(){
	                            	return d.lineColor = "" ? lineColor:d.lineColor;
	                            });
	                        	
	                        	return "url(#arrow" + i + ")";
	                        })
	                        .style("stroke",function(d){
	                        	if(d.lineColor == ""){
                                    return lineColor;
                                }else{
                                	return d.lineColor;
                                }
	                        })
	                        .style("stroke-width",1.5)
	                        .on("mouseover",function(d){
	                        	//影藏其它连线上文字
                                edges_text.style("fill-opacity",function(edge){
                                    if(edge === d){
                                        return 1;
                                    }
                                    return 0;
                                })
                                edges_path.style("stroke-width",function(edge){
                                	if(edge === d){
                                        return 4;
                                    }
                                    return 1.5;
                                })
	                        })
	                        .on("mouseout",function(d,i){
	                        	//显示连线上的文字
                                edges_text.style("fill-opacity",1);
                                edges_path.style("stroke-width",1.5);
	                        });
	                        
	
	    //边上的文字（人物之间的关系）            
	    var edges_text = svg.selectAll(".linetext")
	                        .data(links)
	                        .enter()
	                        .append("svg:g")
	                        .attr("class", "linetext")
	                        .attr("fill-opacity",1);
	        edges_text.append("svg:text")          
                      .style("font-size",(lineFontSize+"px"))
                      .style("font-family",lineFontType)
                      .style("fill","#000000")
                      .attr("y", ".31em")
                      .attr('text-anchor', "middle")
                      .text(function(d){
                          return d.relation;
                      });
	
	    edges_text.insert('rect', 'text')
			      .attr('width', function(d){
			    	  return d.relation.length*lineFontSize;
			      })
			      .attr('height', function(d){
			    	  return lineFontSize;
			      })
			      .attr("y", "-.6em")
			      .attr('x', function (d) {
			          return -d.relation.length*lineFontSize/2;
			      })
			      .style('fill', '#fff');
	
	    // 圆形图片节点（人物头像）
	    var circle = svg.selectAll("circle")
	                        .data(nodes)
	                        .enter()
	                        .append("circle")
	                        .style("stroke",function(d){
                        		if(d.color == ""){
                                    return "#EE8262";
                                }
                                return d.color;
	                        })
	                        .style("stroke-width","2px")
	                        .attr("r", function(d){
	                        	return d.radius;
	                        })
	                        .attr("fill", function(d,i){
	                        	//节点图片不为空是添加背景色
	                        	if(d.image == ""){
	                        		if(d.color == ""){
	                                    return "#EE8262";
	                                }
	                                return d.color;
	                        	}else{
	                        		//创建圆形图片
	                                var defs = svg.append("defs").attr("id", "imgdefs")
	    
	                                var catpattern = defs.append("pattern")
	                                                        .attr("id", "catpattern" + i)
	                                                        .attr("height", 1)
	                                                        .attr("width", 1)
	    
	                                catpattern.append("image")
	                                        /* .attr("x", - (img_w / 2 - radius))
	                                        .attr("y", - (img_h / 2 - radius)) */
	                                        .attr("width", d.radius*2)
	                                        .attr("height", d.radius*2)
	                                        .attr("xlink:href", d.image)
	    
	                                return "url(#catpattern" + i + ")";
	                        	}
	                        	
	                        })
	                        .on("mouseover",function(d,i){
	                        	//影藏其它连线上文字
                                edges_text.style("fill-opacity",function(edge){
                                    if( edge.source === d || edge.target === d ){
                                        return 1;
                                    }
                                    if( edge.source !== d && edge.target !== d ){
                                        return 0;
                                    }
                                })
                                //其它节点亮度调低
                                circle.style("opacity",function(edge){
                                    var v = d.name;
                                    if( edge.name == v || (edge[v] != undefined &&  edge[v].name == v)){
                                        return 1;
                                    }else{
                                        return 0.2;
                                    }
                                })
                                //其他连先亮度调低
                                edges_path.style("opacity",function(edge){
                                    if( edge.source === d || edge.target === d ){
                                        return 1;
                                    }
                                    if( edge.source !== d && edge.target !== d ){
                                        return 0.2;
                                    }
                                })
                                //其他节点文字亮度调低
                                nodes_text.style("opacity",function(edge){
                                    var v = d.name;
                                    if( edge.name == v || (edge[v] != undefined &&  edge[v].name == v)){
                                        return 1;
                                    }else{
                                        return 0.2;
                                    }
                                })
	                        
	                        })
	                        .on("mouseout",function(d,i){
	                        	//显示连线上的文字
                                edges_text.style("fill-opacity",1);
                                edges_path.style("opacity",1);
                                circle.style("opacity",1);
                                nodes_text.style("opacity",1);
                                tooltip.style("opacity",0.0);
	                        
	                        })
	                        .call(force.drag);
	
	    var tooltip = d3.select("body").append("div")
                         .attr("class","tooltip")
                         .attr("opacity",0.0);
	    
	    
	    var nodes_text = svg.selectAll(".nodetext")
	                        .data(nodes)
	                        .enter()
	                        .append("text")
	                        .style("font-size",(nodesFontSize+"px"))
	                        .style("font-family",nodesFontType)
	                        .attr('x',function(d){
						        var name = d.name;
						        //如果小于四个字符，不换行
						        if(name.length < 4){
						             d3.select(this).append('tspan')
						               .attr("dx",-nodesFontSize*(name.length/2))
						               .text(function(){return name;});
						        }else if(name.length >= 4 && name.length <= 6) {
						            var top=d.name.substring(0,3);
						            var bot=d.name.substring(3,name.length);
						
						            d3.select(this).append('tspan')
						                .attr("dx",-nodesFontSize*1.5)
                                        .attr("dy",-nodesFontSize*0.5)
						                .text(function(){return top;});
						
						            d3.select(this).append('tspan')
						                .attr("dx",-(nodesFontSize*name.length/2))
                                        .attr("dy",nodesFontSize)
						                .text(function(){return bot;});
						        }else if(name.length > 7){
						        	var top=d.name.substring(0,3);
                                    var mid=d.name.substring(3,6);
                                    var bot=d.name.substring(6,name.length);
                                    
                                    d3.select(this).append('tspan')
                                        .attr("dx",-nodesFontSize*1.5)
                                        .attr("dy",-nodesFontSize*0.5)
                                        .text(function(){return top;});
                                    
                        
                                    d3.select(this).append('tspan')
                                        .attr("dx",-nodesFontSize*3)
                                        .attr("dy",nodesFontSize)
                                        .text(function(){return mid;});
                                    
                                    d3.select(this).append('tspan')
                                        .attr("dx",-nodesFontSize*2)
                                        .attr("dy",nodesFontSize)
                                        .text(function(){return "...";});
						        }
						    })
						    .on("mouseover",function(d,i){
					            //影藏其它连线上文字
					            edges_text.style("fill-opacity",function(edge){
					                if( edge.source === d || edge.target === d ){
					                    return 1;
					                }
					                if( edge.source !== d && edge.target !== d ){
					                    return 0;
					                }
					            })
					            //其他节点亮度调低
                                circle.style("opacity",function(edge){
                                	var v = d.name;
                                    if( edge.name == v || (edge[v] != undefined &&  edge[v].name == v)){
                                        return 1;
                                    }else{
                                    	return 0.2;
                                    }
                                })
                                //其他连线亮度调低
                                edges_path.style("opacity",function(edge){
                                    if( edge.source === d || edge.target === d ){
                                        return 1;
                                    }
                                    if( edge.source !== d && edge.target !== d ){
                                        return 0.2;
                                    }
                                })
                                //其他节点文字亮度调低
                                nodes_text.style("opacity",function(edge){
                                	var v = d.name;
                                    if( edge.name == v || (edge[v] != undefined &&  edge[v].name == v)){
                                        return 1;
                                    }else{
                                        return 0.2;
                                    }
                                })
                                tooltip.html("<span>"+d.name+"</span>")
                                       .style("left",(d3.event.pageX)+"px")
                                       .style("top",(d3.event.pageY+20)+"px")
                                       .style("display","block")
                                       .style("opacity",1.0);
					        })
	                        .on("mouseout",function(d,i){
                                //显示连线上的文字
                                edges_text.style("fill-opacity",1);
                                edges_path.style("opacity",1);
                                circle.style("opacity",1);
                                nodes_text.style("opacity",1);
                                tooltip.style("opacity",0.0);
                            
                            })
                            .call(force.drag);
						   
	    var drag = force.drag()
				        .on("dragstart",function(d,i){
				            d.fixed = true;    //拖拽开始后设定被拖拽对象为固定
				        })
				        .on("dragend",function(d,i){
				        })
				        .on("drag",function(d,i){
				        });
	
	   //力学图运动开始时
        force.on("start", function(){
        });
        
        //力学图运动结束时
        force.on("end", function(){
        });
	    
	    force.on("tick", function(){
	        //限制结点的边界
	        nodes.forEach(function(d,i){
	            d.x = d.x - 45 < 0 ? 45 : d.x ;
	            d.x = d.x + 45 > width ? width - 45 : d.x ;
	            d.y = d.y - 45 < 0 ? 45 : d.y ;
	            d.y = d.y + 45 > height ? height - 45 : d.y ;
	        });
	
	        edges_path.attr("d", function(d) {  
	        	var tan = Math.abs((d.target.y - d.source.y)/(d.target.x - d.source.x)); //圆心连线tan值
                var x1 = d.target.x - d.source.x > 0 ? Math.sqrt(d.sourceRadius*d.sourceRadius/(tan*tan + 1)) + d.source.x :
                     d.source.x - Math.sqrt(d.sourceRadius*d.sourceRadius/(tan*tan + 1)); //起点x坐标
                var y1 = d.target.y - d.source.y > 0 ? Math.sqrt(d.sourceRadius*d.sourceRadius*tan*tan/(tan*tan + 1)) + d.source.y :
                    d.source.y - Math.sqrt(d.sourceRadius*d.sourceRadius*tan*tan/(tan*tan + 1)); //起点y坐标
                var x2 = d.target.x - d.source.x > 0 ? d.target.x - Math.sqrt(d.targetRadius*d.targetRadius/(1+tan*tan)) :
                        d.target.x + Math.sqrt(d.targetRadius*d.targetRadius/(1+tan*tan));//终点x坐标
                var y2 = d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt(d.targetRadius*d.targetRadius*tan*tan/(1+tan*tan)) :
                    d.target.y + Math.sqrt(d.targetRadius*d.targetRadius*tan*tan/(1+tan*tan));//终点y坐标
                if(d.target.x - d.source.x == 0 || tan == 0){ //斜率无穷大的情况或为0时
                	y1 = d.target.y - d.source.y > 0 ? d.source.y + d.sourceRadius:d.source.y - d.sourceRadius;
                	y2 = d.target.y - d.source.y > 0 ? d.target.y - d.targetRadius:d.target.y + d.targetRadius;
                }
	            if(d.linknum==0){//设置编号为0的连接线为直线，其他连接线会均分在两边  
	            	d.x_start = x1;
	            	d.y_start = y1;
	            	d.x_end = x2;
	            	d.y_end = y2;
	            	return 'M'+x1+' '+y1+' L '+ x2 +' '+y2;
	            }
	            var a = d.sourceRadius > d.targetRadius ? d.targetRadius*d.linknum/3 : d.sourceRadius*d.linknum/3;
	            var xm =d.target.x - d.source.x > 0 ? d.source.x + Math.sqrt((d.sourceRadius*d.sourceRadius-a*a)/(1+tan*tan)):
	            	d.source.x - Math.sqrt((d.sourceRadius*d.sourceRadius-a*a)/(1+tan*tan));
	            var ym =d.target.y - d.source.y > 0 ? d.source.y + Math.sqrt((d.sourceRadius*d.sourceRadius-a*a)*tan*tan/(1+tan*tan)):
	            	d.source.y - Math.sqrt((d.sourceRadius*d.sourceRadius-a*a)*tan*tan/(1+tan*tan));
	            var xn =d.target.x - d.source.x > 0 ? d.target.x - Math.sqrt((d.targetRadius*d.targetRadius-a*a)/(1+tan*tan)):
	            	d.target.x + Math.sqrt((d.targetRadius*d.targetRadius-a*a)/(1+tan*tan));
	            var yn =d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt((d.targetRadius*d.targetRadius-a*a)*tan*tan/(1+tan*tan)):
	            	d.target.y + Math.sqrt((d.targetRadius*d.targetRadius-a*a)*tan*tan/(1+tan*tan));
	            if(d.target.x - d.source.x == 0 || tan == 0){//斜率无穷大或为0时
	            	ym = d.target.y - d.source.y > 0 ? d.source.y + Math.sqrt(d.sourceRadius*d.sourceRadius-a*a):d.source.y - Math.sqrt(d.sourceRadius*d.sourceRadius-a*a);
	            	yn = d.target.y - d.source.y > 0 ? d.target.y - Math.sqrt(d.targetRadius*d.targetRadius-a*a):d.target.y + Math.sqrt(d.targetRadius*d.targetRadius-a*a);
	            }
	            
	            var k = (x1-x2)/(y2-y1);//连线垂线的斜率
	            var dx = Math.sqrt(a*a/(1+k*k)); //相对垂点x轴距离
                var dy = Math.sqrt(a*a*k*k/(1+k*k)); //相对垂点y轴距离
                if((y2-y1) == 0){
                    dx = 0;
                    dy = Math.sqrt(a*a);
                }
	            if(a > 0){
	            	var xs = k > 0 ? xm - dx : xm + dx;
	            	var ys = ym - dy;
	            	var xt = k > 0 ? xn - dx : xn + dx;
	            	var yt = yn - dy;
	            }else{
	            	var xs = k > 0 ? xm + dx : xm - dx;
                    var ys = ym + dy;
                    var xt = k > 0 ? xn + dx : xn - dx;
                    var yt = yn + dy;
	            }
	            //记录连线起始和终止坐标，用于定位线上文字
	            d.x_start = xs;
                d.y_start = ys;
                d.x_end = xt;
                d.y_end = yt;
	            return 'M'+xs+' '+ys+' L '+ xt +' '+yt;
	          }); 
	
	         //更新连接线上文字的位置
	          edges_text.attr("transform", function (d) {
                  return "translate(" + (d.x_start + d.x_end)/2 + "," + (d.y_start + d.y_end)/2 + ")" + " rotate(" + Math.atan((d.y_end - d.y_start) / (d.x_end - d.x_start)) * 180 / Math.PI + ")";
              });
	      	
	
	         //更新结点图片和文字
	         circle.attr("cx",function(d){ return d.x });
	         circle.attr("cy",function(d){ return d.y });
	
	         nodes_text.attr("x",function(d){ return d.x });
	         nodes_text.attr("y",function(d){ return d.y });
	    });
}


function setLinkNumber(group){   
    if(group.length==0) return;
    if(group.length==1){
    	group[0].linknum = 0;
    	return;
    }
    var maxLinkNumber = group.length%2==0?group.length/2:(group.length-1)/2;
    if(group.length%2==0){
    	var startLinkNum = -maxLinkNumber + 0.5;
        for(var i = 0;i<group.length;i++){
            group[i].linknum = startLinkNum++;
        }
    }else{
    	var startLinkNum = -maxLinkNumber;
        for(var i = 0;i<group.length;i++){
            group[i].linknum = startLinkNum++;
        }
    }
   	
}

</script>


</html>
